
local coroutine = coroutine
local coroutine_create = coroutine.create
local tremove = table.remove

local session_id_coroutine = {}
local session_coroutine_id = {}
local session_coroutine_address = {}
local session_coroutine_tracetag = {}
local cresume = coroutine.resume
local running_thread = nil

local function coroutine_resume(co, ...)
	running_thread = co
	return cresume(co, ...)
end

function fun1(var)
	print('this is ', var)
end

function fun2(var)
	print('this is ', var)
end

function fun3(var)
	print('this is ', var)
end

local coroutine_pool = setmetatable({}, { __mode = "kv" })

local function co_create(f)
	local co = tremove(coroutine_pool)
	if co == nil then
		co = coroutine_create(function(...)
			f(...)
			while true do
				local session = session_coroutine_id[co]
				if session and session ~= 0 then
					local source = debug.getinfo(f,"S")
					skynet.error(string.format("Maybe forgot response session %s from %s : %s:%d",
						session,
						skynet.address(session_coroutine_address[co]),
						source.source, source.linedefined))
				end
				-- coroutine exit
				local tag = session_coroutine_tracetag[co]
				if tag ~= nil then
					if tag then c.trace(tag, "end")	end
					session_coroutine_tracetag[co] = nil
				end
				local address = session_coroutine_address[co]
				if address then
					session_coroutine_id[co] = nil
					session_coroutine_address[co] = nil
				end

				-- recycle co into pool
				f = nil
				coroutine_pool[#coroutine_pool+1] = co
				-- recv new main function f
				f = coroutine_yield "SUSPEND"
				f(coroutine_yield())
			end
		end)
	else
		-- pass the main function f to coroutine, and restore running thread
		local running = running_thread
		coroutine_resume(co, f)
		running_thread = running
	end
	return co
end


-- local _, cmd = coroutine.resume(coroutine_create(fun1), 'fun 1')

-- _, cmd = coroutine.resume(coroutine_create(fun2), 'fun 2')

-- _, cmd = coroutine.resume(coroutine_create(fun3), 'fun 3')

local t1 = os.time()
local m1 = collectgarbage('count')
for i = 1, 1000 do
	--coroutine.resume(coroutine.create(fun1))       --第一次
	coroutine.resume(co_create(fun1))                --第二次用协程池
end
local m2 = collectgarbage('count')
local t2 = os.time()
print('diff time is ', t2 - t1)
print('diff mem is ', m2 - m1)
--[[
    diff time is    0
    diff mem is     4.7890625

    diff time is    0
    diff mem is     4.2861328125
]]

